﻿using CommonLibraries.DeviceLibrary;
using PolePositionMobile.Entities;
using PolePositionMobile.Logic;
using System;
using System.Linq;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Text;
using System.Windows.Forms;

namespace PolePositionMobile
{
    /// <summary>
    /// A form that manages a visit's images
    /// </summary>
    public partial class frmPhotos : frmBase
    {
        //Created by: VMCoder
        //Creation date: -
        //Last updated by: VMCoder
        //Last update: 2008.04.10
        #region Private Members
        private EVisit m_Visit;
        private bool m_EnableTabs = true;
        private List<PoleId> m_PoleIdList;
        private List<EImage> m_Images;
        #endregion
        #region Protected Members
        protected Camera m_Camera = Camera.GetInstance();
        #endregion
        #region Public Properties
        public bool EnableTabs
        {
            get { return m_EnableTabs; }
            set { m_EnableTabs = value; }
        }
        public EVisit Visit
        {
            get { return m_Visit; }
            set { m_Visit = value; }
        }
        #endregion

        public frmPhotos()
        {
            InitializeComponent();
        }
        protected void frmPhotos_Load(object sender, EventArgs e)
        {
            #region Config form
            lblTitle.Text = "PPI | Transmission Locating";
            lblLButtonText.Text = "Menu";
            lblRButtonText.Text = "Finish";
            lblLButton.ContextMenu = menLButton;
            LButtonMenuXOffset = 1;
            LButtonMenuYOffset = 116;
            tbcTabs.SelectedIndex = 2;
            tbcTabs.Visible = true;
            tbcTabs.Enabled = m_EnableTabs;
            PolesNumber = m_Visit.Data != null && m_Visit.Data.Poles != null ? m_Visit.Data.Poles.Length : 0;
            PhotosNumber = m_Visit.Images != null ? m_Visit.Images.Length : 0;
            #endregion
            EnableCamera();
            LoadCombos();
            if (m_Visit.Images != null && m_Visit.Images.Length > 0)
                m_Images = m_Visit.Images.ToList();
            else
                m_Images = new List<EImage>();
            if (m_Visit.ImagesToDelete == null)
                m_Visit.ImagesToDelete = new List<Int32>();
            if (m_Visit.FilesToDelete == null)
                m_Visit.FilesToDelete = new List<string>();
            ShowList();
        }
        private void EnableCamera()
        {
            if (m_Camera.PowerState == PowerStates.Off)
                m_Camera.On(pictureBoxPreviewPhoto.Location.X + (pictureBoxPreviewPhoto.Size.Width / 2 - 160 / 2), pictureBoxPreviewPhoto.Location.Y + (pictureBoxPreviewPhoto.Size.Height / 2 - 120 / 2));
            else
                m_Camera.SetCameraFinder((int)PowerStates.On, pictureBoxPreviewPhoto.Location.X, pictureBoxPreviewPhoto.Location.Y);
        }
        private void DisableCamera()
        {
            m_Camera.Off(0, 0);
        }
        private void DisableCameraFinder()
        {
            m_Camera.SetCameraFinder((int)PowerStates.Off, 0, 0);
        }
        private void LoadCombos()
        {
            #region Poles
            PoleId _PoleId = new PoleId();
            m_PoleIdList = new List<PoleId>();
            ddlPoles.BeginUpdate();
            ddlPoles.Items.Add("[Structure]");
            _PoleId._Num = Int32.MinValue;
            _PoleId._NumIsId = true;
            m_PoleIdList.Add(_PoleId);
            if (m_Visit.Data != null && m_Visit.Data.Poles != null)
            {
                for (Int32 _I = 1; _I <= m_Visit.Data.Poles.Length; _I++)
                {
                    ddlPoles.Items.Add("Pole " + (_I).ToString() + " (" + m_Visit.Data.Poles[_I - 1].SatelliteTime.AddMinutes(m_Settings.Timezone * 60).ToString("hh:mmtt") + ")");
                    if (m_Visit.Data.Poles[_I - 1].PoleId != Int32.MinValue)
                    {
                        _PoleId._Num = m_Visit.Data.Poles[_I - 1].PoleId;
                        _PoleId._NumIsId = true;
                    }
                    else
                    {
                        _PoleId._Num = _I - 1;
                        _PoleId._NumIsId = false;
                    }
                    m_PoleIdList.Add(_PoleId);
                }
            }
            if (ddlPoles.Items.Count > 0)
                ddlPoles.SelectedIndex = 0;
            ddlPoles.EndUpdate();
            #endregion Poles
        }
        protected override void lblClose_Click(object sender, EventArgs e)
        {
            DisableCamera();
            ShowLoading();
            Application.DoEvents();
            for (Int32 _I = m_Images.Count - 1; _I >= 0; _I--)
                if (m_Images[_I].ImageId == Int32.MinValue)
                    RemoveImage(_I);
            if (MessageBox.Show("Are you sure you want to exit?", PPIConstants.K_AppName, MessageBoxButtons.YesNo, MessageBoxIcon.None, MessageBoxDefaultButton.Button2) == DialogResult.Yes)
                Application.Exit();
        }
        protected override void lblRButton_Click(object sender, EventArgs e)
        {
            ShowLoading();
            Application.DoEvents();
            m_Visit.Images = m_Images.ToArray();
            if (m_Images.Count >= 3)
            {
                LogicLayer.SaveCompleteVisit(m_Visit,this.Settings);
                foreach (string _ImageToDelete in m_Visit.FilesToDelete)
                    if (File.Exists(PPIConstants.K_ImagesFolder + _ImageToDelete))
                        File.Delete(PPIConstants.K_ImagesFolder + _ImageToDelete);
                frmHomePage _Form = new frmHomePage();
                DisableCamera();
                _Form.Settings = this.Settings;
                _Form.Show();
            }
            else
            {
                frmInsufficientPhotosDialog _Dialog = new frmInsufficientPhotosDialog();
                _Dialog.Visit = m_Visit;
                _Dialog.Settings = this.Settings;
                DisableCamera();
                _Dialog.Show();
            }
            this.Hide();
        }

        private void mitCancel_Click(object sender, EventArgs e)
        {
            DisableCamera();
            ShowLoading();
            Application.DoEvents();
            frmHomePage _Form = new frmHomePage();
            for (Int32 _I = m_Images.Count - 1; _I >= 0; _I--)
                if (m_Images[_I].ImageId == Int32.MinValue)
                    RemoveImage(_I);
            _Form.Settings = this.Settings;
            _Form.Show();
            this.Hide();
        }

        private void lstImages_SelectedIndexChanged(object sender, EventArgs e)
        {
            PoleId _PoleId = new PoleId();
            mitDeletePhoto.Enabled = lstImages.SelectedIndex > -1;
            if (lstImages.SelectedIndex > -1)
            {
                EImage _Image = m_Images[lstImages.SelectedIndex];

                _PoleId._Num = _Image.PoleFk;
                _PoleId._NumIsId = _Image.PoleFkIsId;
                ddlPoles.SelectedIndex = m_PoleIdList.IndexOf(_PoleId);
                DisableCamera();
                pictureBoxPreviewPhoto.Image = String.IsNullOrEmpty(_Image.Filename) || !File.Exists(PPIConstants.K_ImagesFolder + _Image.Filename) ? null : ImageHelper.GetImage(PPIConstants.K_ImagesFolder + _Image.Filename);

                cmdAdd.Text = "Save";
            }
            else
                cmdAdd.Text = "Add";
        }

        private void cmdAdd_Click(object sender, EventArgs e)
        {
            SaveImage();
        }
        private void SaveImage()
        {
            string _ErrMsg = "";
            if (_ErrMsg != "")
                MessageBox.Show(_ErrMsg, PPIConstants.K_AppName);
            else
            {
                EImage _Image = lstImages.SelectedIndex > -1 ? m_Images[lstImages.SelectedIndex] : new EImage();
                _Image.PoleFk = (Int32)m_PoleIdList[ddlPoles.SelectedIndex]._Num;
                _Image.PoleFkIsId = (bool)m_PoleIdList[ddlPoles.SelectedIndex]._NumIsId;
                if (_Image.ImageId == Int32.MinValue)
                    _Image.Filename = "temp_" + (lstImages.SelectedIndex > -1 ? lstImages.SelectedIndex : m_Images.Count) + ".jpeg";
                else
                    _Image.Filename = _Image.ImageId + ".jpeg";

                if (lstImages.SelectedIndex > -1 || TakePhoto(PPIConstants.K_ImagesFolder + _Image.Filename))
                {
                    if (m_GPS.HasSolution)
                    {
                        string stemp = "";
                        _Image.Longitude = Utils.ConvertLongitudeToDecimal(m_GPS.NmeaGGA.Longitude, m_GPS.NmeaGGA.LongitudeHemisphere, ref stemp);
                        _Image.Latitude = Utils.ConvertLatitudeToDecimal(m_GPS.NmeaGGA.Latitude, m_GPS.NmeaGGA.LatitudeHemisphere, ref stemp);
                        _Image.Altitude = double.Parse(m_GPS.NmeaGGA.Altitude.ToString());
                        _Image.SatelliteCount = m_GPS.NmeaGGA.SateliteCount;
                        _Image.SatelliteTime = m_GPS.NmeaGGA.SateliteTime;
                        _Image.SolutionAvailable = true;
                    }
                    else if (_Image.PoleFk != Int32.MinValue)
                    {
                        _Image.Longitude = m_Visit.Data.Poles[ddlPoles.SelectedIndex -1].Longitude;
                        _Image.Latitude = m_Visit.Data.Poles[ddlPoles.SelectedIndex - 1].Latitude;
                        _Image.Altitude = m_Visit.Data.Poles[ddlPoles.SelectedIndex - 1].Altitude;
                        _Image.SatelliteCount = m_Visit.Data.Poles[ddlPoles.SelectedIndex - 1].SatelliteCount;
                        _Image.SatelliteTime = DateTime.Now.ToUniversalTime();
                        _Image.SolutionAvailable = false;
                    }
                    else
                    {
                        _Image.Longitude = m_Visit.Longitude;
                        _Image.Latitude = m_Visit.Latitude;
                        _Image.Altitude = m_Visit.Altitude;
                        _Image.SatelliteCount = m_Visit.SatelliteCount;
                        _Image.SatelliteTime = DateTime.Now.ToUniversalTime();
                        _Image.SolutionAvailable = false;
                    }

                    if (lstImages.SelectedIndex > -1)
                        m_Images[lstImages.SelectedIndex] = _Image;
                    else
                        m_Images.Add(_Image);
                    ShowList();
                    Clear();
                }
            }
        }
        private bool TakePhoto(string FileName)
        {
            lblTakingPhoto.Visible = true;
            Application.DoEvents();
            int i = 0;
            bool _Taken = false;
            while (i < 3 && !_Taken)
            {
                DisableCameraFinder();
                m_Camera.TakePhoto(FileName, 1);

                if (File.Exists(FileName))
                    _Taken = true;
                else
                {
                    GC.Collect();
                    if (i == 2)
                    {
                        DisableCamera();
                        MessageBox.Show(Constants.K_AlertImposibleTakePhoto, PPIConstants.K_AppName);
                        EnableCamera();
                        return false;
                    }
                }
                i++;
            }
            lblTakingPhoto.Visible = false;
            Application.DoEvents();
            return true;
        }
        private void ShowList()
        {
            string _TempString;
            PhotosNumber = m_Images.Count;
            lstImages.Items.Clear();
            for (Int32 _I = 0; _I < m_Images.Count; _I++)
            {
                _TempString = "Image " + (_I + 1).ToString();
                if (m_Images[_I].PoleFk != Int32.MinValue)
                {
                    if (m_Images[_I].PoleFkIsId)
                    {
                        PoleId _PoleId = new PoleId();
                        _PoleId._Num = m_Images[_I].PoleFk;
                        _PoleId._NumIsId = m_Images[_I].PoleFkIsId;
                        _TempString += "/Pole " + (m_PoleIdList.IndexOf(_PoleId)).ToString();
                    }
                    else
                        _TempString += "/Pole " + (m_Images[_I].PoleFk).ToString();
                }
                _TempString += (m_Images[_I].SatelliteTime != DateTime.MinValue ? " (" + m_Images[_I].SatelliteTime.AddMinutes(m_Settings.Timezone * 60).ToString("hh:mmtt") + ")" : "");
                lstImages.Items.Add(_TempString);
            }
            lstImages.SelectedIndex = -1;
            lstImages_SelectedIndexChanged(null, null);
        }
        private void cmdClear_Click(object sender, EventArgs e)
        {
            Clear();
        }
        private void Clear()
        {
            lstImages.SelectedIndex = -1;
            ddlPoles.SelectedIndex = 0;
            pictureBoxPreviewPhoto.Image = null;
            ShowLoading();
            Application.DoEvents();
            DisableCamera();
            EnableCamera();
            HideLoading("PPI | Transmission Locating");
        }

        private void mitDeleteImage_Click(object sender, EventArgs e)
        {
            if (lstImages.SelectedIndex > -1)
            {
                ShowLoading();
                Application.DoEvents();
                RemoveImage(lstImages.SelectedIndex);
                RemapImages(lstImages.SelectedIndex);
                HideLoading("PPI | Transmission Locating");
            }
            ShowList();
            Clear();
        }
        private void RemoveImage(Int32 index)
        {
            if (m_Images[index].ImageId != Int32.MinValue)
            {
                m_Visit.ImagesToDelete.Add(m_Images[index].ImageId);
                m_Visit.FilesToDelete.Add(m_Images[index].Filename);
            }
            else if (File.Exists(PPIConstants.K_ImagesFolder + m_Images[index].Filename))
                File.Delete(PPIConstants.K_ImagesFolder + m_Images[index].Filename);
            m_Images.RemoveAt(index);
        }
        private void RemapImages(Int32 startIndex)
        {
            for (Int32 _I = startIndex; _I < m_Images.Count; _I++)
            {
                if (m_Images[_I].ImageId == Int32.MinValue)
                {
                    if (File.Exists(PPIConstants.K_ImagesFolder + m_Images[_I].Filename))
                        File.Move(PPIConstants.K_ImagesFolder + m_Images[_I].Filename, PPIConstants.K_ImagesFolder + "temp_" + _I.ToString() + ".jpeg");
                    m_Images[_I].Filename = "temp_" + _I.ToString() + ".jpeg";
                }
            }
        }
        private void mitAddImage_Click(object sender, EventArgs e)
        {
            if (lstImages.SelectedIndex > -1)
                Clear();
            else
                SaveImage();
        }

        protected override void tabMain_Click(object sender, EventArgs e)
        {
            ShowLoading();
            Application.DoEvents();
            m_Visit.Images = m_Images.ToArray();
            DisableCamera();
            frmDataCollectionStructure _Form = new frmDataCollectionStructure();
            _Form.Visit = m_Visit;
            _Form.Settings = this.Settings;
            _Form.Show();
            this.Hide();
        }
        protected override void tabPoles_Click(object sender, EventArgs e)
        {
            ShowLoading();
            Application.DoEvents();
            m_Visit.Images = m_Images.ToArray();
            frmDataCollectionPole _Form = new frmDataCollectionPole();
            _Form.Visit = m_Visit;
            _Form.TakePhotos = true;
            DisableCamera();
            _Form.Settings = this.Settings;
            _Form.Show();
            this.Hide();
        }

        private void pictureBoxPreviewPhoto_Click(object sender, EventArgs e)
        {
            if (pictureBoxPreviewPhoto.Image != null)
                menZoom.Show(pictureBoxPreviewPhoto, new Point(pictureBoxPreviewPhoto.Width / 2, pictureBoxPreviewPhoto.Height / 2));
        }

        private void ShowZoom(Int32 width, Int32 height)
        {
            ShowLoading();
            Application.DoEvents();
            PictureBox _PbxImage = new PictureBox();
            _PbxImage.Location = new Point(0, 0);
            _PbxImage.Size = new Size(width, height);
            _PbxImage.SizeMode = PictureBoxSizeMode.StretchImage;
            _PbxImage.Image = pictureBoxPreviewPhoto.Image;
            Form _FormZoomImage = new Form();
            #region Configure form
            _FormZoomImage.SuspendLayout();
            _FormZoomImage.AutoScaleDimensions = new SizeF(96F, 96F);
            _FormZoomImage.AutoScaleMode = AutoScaleMode.Dpi;
            _FormZoomImage.AutoScroll = true;
            _FormZoomImage.ClientSize = new Size(238, 297);
            _FormZoomImage.Controls.Add(_PbxImage);
            _FormZoomImage.MaximizeBox = false;
            _FormZoomImage.MinimizeBox = false;
            _FormZoomImage.Text = "PPI | Zoom Image";
            _FormZoomImage.TopMost = true;
            _FormZoomImage.ResumeLayout(false);
            #endregion Configure form
            HideLoading("PPI | Transmission Locating");
            Application.DoEvents();
            _FormZoomImage.ShowDialog();
        }

        private void mit320x240_Click(object sender, EventArgs e)
        {
            ShowZoom(320, 240);
        }

        private void mit640x480_Click(object sender, EventArgs e)
        {
            ShowZoom(640, 480);
        }
    }
}
